#pragma once
#include "channel.hpp"
using namespace std;

namespace rbmq {
    class Connection {
    public :
        typedef shared_ptr<Connection> ptr;
        Connection(const VirtualHost::ptr& virtualHost, const consumerManager::ptr& cmp, const ProtobufCodecPtr& codec, \
                            const muduo::net::TcpConnectionPtr& connection, const threadpoolPtr& pool) 
            :_connection(connection)
            ,_codec(codec)
            ,_cmp(cmp)
            ,_virtualHost(virtualHost)
            ,_threadpool(pool)     
            ,_channels(make_shared<channelManager>())       
        {

        }
        ~Connection() {
        }

        // 打开一个信道
        void openChannle(const openChannelRequestPtr& req) 
        {
            // 1、判断信道id是否重复，通过信道管理句柄创建信道
            bool res = _channels->openChannel(_virtualHost, _cmp, _codec, _connection, req->cid(), _threadpool);
            if (!res) {
                return basicResponse(req->rid(), req->cid(), false);
            }
            // 2、个客户端进行回复
            basicResponse(req->rid(), req->cid(), true);
        }
        // 关闭一个信道
        void closeChannel(const closeChannelRequestPtr& req) {
            _channels->closeChannel(req->cid());
            basicResponse(req->rid(), req->cid(), true);
        }

        // 获取一特信道
        channel::ptr getChannel(const string& cid) {
            return _channels->getChannel(cid);
        }

    private :
    // 进行统一的响应
    void basicResponse(const string& rid, const string& cid, bool ok) {
        // 构建统一响应对象，使用_codec进行发送
        mqNs::basicCommonResponse resp;
        resp.set_ok(ok);
        resp.set_rid(rid);
        resp.set_cid(cid);
        _codec->send(_connection, resp);
    }


    private :
        muduo::net::TcpConnectionPtr _connection; // 信道所关联的连接
        ProtobufCodecPtr _codec; // 信道的protobuf协议处理器
        consumerManager::ptr _cmp; // 消费者管理句柄
        VirtualHost::ptr _virtualHost; // 虚拟机管理句柄
        threadpoolPtr _threadpool; // 线程池
        channelManager::ptr _channels; // 当前连接所管理的所有的信道
    };

    // 连接的管理类
    class ConnectionManager {
    public :
        typedef shared_ptr<ConnectionManager> ptr;
        ConnectionManager() {

        }

        // 创建一个链接
        void createConnecion(const VirtualHost::ptr& virtualHost, const consumerManager::ptr& cmp, const ProtobufCodecPtr& codec, \
                            const muduo::net::TcpConnectionPtr& connection, const threadpoolPtr& pool) 
        {
            unique_lock<mutex> lock(_mutex);
            auto it = _connections.find(connection);
            if (it != _connections.end()) {
                return ;
            }
            // 创建一个Connection智能指针对象
            Connection::ptr conn = make_shared<Connection>(virtualHost, cmp, codec, connection, pool);
            _connections.insert(make_pair(connection, conn));
            if (_connections.count(connection)) {
                LOG(Debug) << "创建新连接成功……………………" << endl;
            }
        }

        // 删除一个链接
        void deleteConnection(const muduo::net::TcpConnectionPtr& connection) {
            unique_lock<mutex> lock(_mutex);
            auto it = _connections.find(connection);
            if (it == _connections.end()) {
                return ;
            }
            _connections.erase(connection);
        }

        // 获取一个链接
        Connection::ptr getConneciont(const muduo::net::TcpConnectionPtr& connection) {
            unique_lock<mutex> lock(_mutex);
            auto it = _connections.find(connection);
            if (it == _connections.end()) {
                return Connection::ptr();
            }
            return it->second;
        }
    private :
        mutex _mutex;
        unordered_map<muduo::net::TcpConnectionPtr, Connection::ptr> _connections;

    };

};